from django import forms
from django.core.exceptions import ValidationError
import redis

from captcha.fields import CaptchaField
from MxOnline.settings import REDIS_HOST, REDIS_PORT
from .models import UserProfile


def validate_even(value):
    if len(value) > 200:
        raise ValidationError('密码太长了！')


# 账号密码登录表单
class LoginForm(forms.Form):
    username = forms.CharField(required=True, min_length=2)  # 这里的列名必须跟前端的表单元素的 name 一致
    password = forms.CharField(required=True, min_length=3, validators=[validate_even])


# 图片验证码表单，只要求用户提交手机号码与图片验证码，当用户点击发送手机验证码时触发
class DynamicLoginForm(forms.Form):
    mobile = forms.CharField(required=True, min_length=11, max_length=11)
    captcha = CaptchaField()


# 动态登录时的手机验证码表单，只要求用户提交手机号码与手机验证码，当用户输入手机验证码并点击登录按钮时触发
class DynamicLoginPostForm(forms.Form):
    mobile = forms.CharField(required=True, min_length=11, max_length=11)
    code = forms.CharField(required=True, min_length=4, max_length=4)

    # 自定义 code 字段验证，验证用户表单输入的手机验证码code是否与库保存的 code是否相同
    def clean_code(self):  # 对 code 字段添加自定义验证方式
        mobile = self.data.get('mobile')
        code = self.data.get('code')  # 用户表单输入的手机验证码

        r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, db=0, decode_responses=True)
        redis_code = r.get(str(mobile))  # redis 保存的手机验证码
        if code != redis_code:  # 两者不相等时抛出异常
            raise forms.ValidationError('填写的手机验证码不正确！')

        return code

    # 该方法是对每个字段进行验证后执行的，不能知道是哪个字段验证出错
    # def clean(self):
    #     mobile = self.cleaned_data['mobile']
    #     code = self.cleaned_data['code']  # 用户表单输入的手机验证码
    #
    #     r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, db=0, decode_responses=True)
    #     redis_code = r.get(str(mobile))  # redis 保存的手机验证码
    #     if code != redis_code:  # 两者不相等时抛出异常
    #         raise forms.ValidationError('填写的手机验证码不正确！')
    #     return self.cleaned_data


# 注册时 首次进入(get 请求) 注册页面时传递的图片验证码表单
class RegisterGetForm(forms.Form):
    captcha = CaptchaField()


# 注册时提交注册请求(post 请求)
class RegisterPostForm(forms.Form):
    mobile = forms.CharField(required=True, min_length=11, max_length=11)
    password = forms.CharField(required=True)
    code = forms.CharField(required=True, min_length=4, max_length=4)

    # 自定义 mobile 字段验证，验证用户表单输入的手机验号是否注册
    def clean_mobile(self):  # 对 code 字段添加自定义验证方式
        mobile = self.data.get('mobile')

        # 验证手机号是否注册
        users = UserProfile.objects.filter(mobile=mobile)
        if users:
            raise forms.ValidationError('该手机号码已经被注册！')

        return mobile

    # 自定义 code 字段验证，验证用户表单输入的手机验证码code是否与库保存的 code是否相同
    def clean_code(self):  # 对 code 字段添加自定义验证方式
        mobile = self.data.get('mobile')
        code = self.data.get('code')  # 用户表单输入的手机验证码

        r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, db=0, decode_responses=True)
        redis_code = r.get(str(mobile))  # redis 保存的手机验证码
        if code != redis_code:  # 两者不相等时抛出异常
            raise forms.ValidationError('填写的手机验证码不正确！')

        return code
